/*
 * syscall.c - Mokri
 * Contributors: xMine
 * (Any new Contributor may add himself/herself to the list)
 * Changes and fixes to be made: Any Task is in Ring0 => Kernel rights
 */

#include "syscall.h"

/* Wird von idt_behandlung aufgerufen */
void syscall_handler (struct stack_frame *sf, struct task *proc) {

	char **cmd;
	//char **argv;
	int elements;
	pid_t pid;
	struct task *t;
	
	switch (sf->eax) {
	case 1:
		print ((char*)sf->ebx);
		break;
	case 2:
		clearscreen ();
		break;
	case 3:
		scrollscreen (sf->ebx);
		break;
	case 4:
		gets ((char*)sf->ebx);
		break;
	case 5:
		sf->ebx = (int)getchar ();
		break;
	case 6:
		sf->ebx = printf_ex ((const char *)sf->ebx, (va_list*)sf->ecx);
		break;
	case 7:
		sf->ebx = (uint32_t)malloc ((uint32_t)sf->ebx);
		break;
	case 8:
		free ((void*)sf->ebx);
		break;
	case 9:
		DestroyTask (GetRunningTaskPID(), (int)sf->ebx);
		break;
	case 10:
		sf->ebx = (uint32_t)fopen ((char*)sf->ebx, (char*)sf->ecx);
		break;
	case 11:
		sf->ebx = (uint32_t)fclose ((FILE*)sf->ebx);
		break;
	case 12:
		sf->ebx = (uint32_t)fread ((char*)sf->ebx, (size_t)sf->ecx, 1, (FILE*)sf->edx);
		break;
	case 13:
		sf->ebx = (uint32_t)fwrite ((char*)sf->ebx, (size_t)sf->ecx, 1, (FILE*)sf->edx);
		break;
	case 14:
		sf->ebx = (uint32_t)fseek ((FILE*)sf->ebx, (int)sf->ecx, (int)sf->edx);
		break;
	case 15:
		sf->ebx = (uint32_t)ftell ((FILE*)sf->ebx);
		break;
	case 16: // TODO: fstat implementieren
		sf->ebx = (uint32_t)-1;
		break;
	case 17:
		sf->ebx = (uint32_t)GetRunningTaskPID();
	case 18:
		DestroyTask ((pid_t)sf->ebx, 0);
		sf->ebx = (uint32_t)0;
		break;
	case 19: // TODO: wait Syscall implementieren
		break;
	case 20:
		cmd = strsplit((char*)sf->ebx, &elements); // Kommandostring holen
		pid = elf_load (cmd[0]);		// Prozess erzeugen
		t = GetTaskStruct (pid);		// Task Struktur holen
		if (t != NULL) {
			t->parent = GetRunningTaskPID ();	// Parent eintragen
			t->flags = TASK_FLAG_WAKEUP_PARENT;	// Der Parent wird nach beenden des Prozesses wieder gestartet
			SetArgumentList (pid, elements, cmd);	// Argumentenliste übergeben
			ResumeTask (pid);			// Nun läuft der Prozess
			sf->ebx = (uint32_t)FreezeTask (GetRunningTaskPID()); // Und nun freezen wir uns selber
		} else {
			sf->ebx = 0;
		}
		break;
	case 21:
		sf->ebx = (uint32_t)opendir ((const char*)sf->ebx);
		break;
	case 22:
		sf->ebx = (uint32_t)(closedir ((DIR*)sf->ebx)+100);
		break;
	case 23:
		sf->ebx = (uint32_t)readdir ((DIR*)sf->ebx);
		break;
	case 24:
		rewinddir ((DIR*)sf->ebx);
		break;
	case 25:
		sf->ebx = (uint32_t)realloc ((void*)sf->ebx, (size_t)sf->ecx);
	case 30:
		fs_get_working_dir ((char*)sf->ebx, (uint32_t)sf->ecx);
		break;
	case 31:
		fs_set_working_dir ((char*)sf->ebx);
		break;
	case 32:
		env_add ((const char*)sf->ebx, (const char*)sf->ecx);
		break;
	case 33:
		sf->ebx = (uint32_t)env_get ((const char*)sf->ebx);
		break;
	case 34:
		env_remove ((const char*)sf->ebx);
		break;
	default:
		printf ("\nUnbekannter Systemcall: %u\n", (uint32_t)sf->eax);
		break;
	}

}
